1 Overview

We have been tasked with cleaning and reorganizing four exisiting data sets. The four data sets each contain different data related to life expectancy in different countries. Our goal will be to combine them into one that can be used for statistical analysis and visualization.

3 of the 4 data sets are organized in a ‘wide’ format. For example, the ‘income’ data set has 220 columns. Column 1 is the country of interest, and each subsequent column is a year, from 1800-2018 (inclusive). Each year variable starts with a capital ‘X’.

2 Cleaning and Re-formatting the Data

We will first condense those 3 data sets to a data set with 3 columns. This will allow an easier merge. In the process of doing this, we will remove the “X” from the start of each year.

ipp.long <- ipp %>%
  pivot_longer(cols = starts_with("X"), names_to = "year", values_to = "income") %>%
  mutate(year = as.numeric(str_remove(year, "^X"))) 

ley.long <- ley %>%
  pivot_longer(cols = starts_with("X"), names_to = "year", values_to = "lifeExp") %>%
  mutate(year = as.numeric(str_remove(year, "^X"))) 

pop.long <- pop %>%
  pivot_longer(cols = starts_with("X"), names_to = "year", values_to = "population") %>%
  mutate(year = as.numeric(str_remove(year, "^X"))) 

We have been asked to create a dataset called LifeExpIncom that only contains Life Expectancy and Income. The requested format is lower case for all variables except for ‘lifeExp’ for life expectancy.

We will also merge the remaining data into one set. The final data sets will replace ‘geo’ with ‘country’, per request of our assignment.

LifeExpIncom <- merge(ipp.long, ley.long, by = c("geo", "year"))

merge.df.1 <- merge(LifeExpIncom, pop.long, by = c("geo", "year"))

colnames(cr)[1]<-"geo"
merge.df.2 <-merge(merge.df.1, cr, by = "geo")

colnames(LifeExpIncom)[1]<-"country"
colnames(merge.df.2)[1]<-"country"

#write.csv(merge.df.2, "C:\\Users\\Alex\\Documents\\R\\Grad\\553\\datasets\\wk5.csv")

Our data is now in one dataset, ready for visualization. A copy of this data can be found at https://raw.githubusercontent.com/AlexDragonetti/STA553/main/hw5/wk5.csv

3 Subsetting the Data to Analyze the Year 2000

We have been asked to create a dataset for the year 2000 and visualize it. First, we must create the data:

"2000data"<-subset(merge.df.2, year==2000)
#for some reason, R encounters an error while viewing "2000data", so I have created a second df that is identical
twothousanddata<-subset(merge.df.2, year==2000)

#write.csv(twothousanddata, "C:\\Users\\Alex\\Documents\\R\\Grad\\553\\datasets\\2000data.csv")

A copy of the above data can be found at https://raw.githubusercontent.com/AlexDragonetti/STA553/main/hw5/2000data.csv

4 Visualizing the Data for the Year 2000

We have been asked to visually represent data from all four sets in one graph, and specifically asked to represent region with a color-code. Population size being represented with point size seems logical, meaning our graph will have income on the X axis and Life Expectancy on the Y axis. This uses the ggplot package.

life.exp.plot<-ggplot(twothousanddata, aes (x=income, y=lifeExp, color=region, size=population))+geom_point()+scale_color_manual(values=c("#332288", "#117733", "#88CCEE", "#CC6677", "#882255"))+
  labs(
  x="Income",
  y="Life Expectancy",
  size="Population",
  color="Region",
  title="Association Between Income and Life Expectancy")

life.exp.plot

Our graph shows evidence of a few trends: first, African and Asian countries appear to have incredibly high variance for life expectancy. Additionally, there appears to be a linear relationship between income and life expectancy, but that (obviously) must stop somewhere. It appears that beyond an average income of ~$40,000 (~$73,000 adjusted for 2024, using the US Bureau of Labor Statistics’ CPI Inflation Calculator), the relationship between income and life expectancy plateaus.

As this is only an analysis of one year, we would suggest analyzing the relationship between income, population size, and life expectancy across multiple years of interest to see if or how this relationship changes, or what it averages to over an era of interest.

5 Using Interactive Plots to Improve Visualization

While our previous plot provides an overview and can help assess trends, we will use two interactive visuals to allow for deeper engagement with data. Our first graph will look similar to our last, but allow a reader to check a country (and its data). Our second will show how the data has changed year to year. For our interactive plots, we will use the plotly package.

5.1 First Interactive plot: Income and Life Expectancy in 2015

df.full<-read.csv("https://raw.githubusercontent.com/AlexDragonetti/STA553/main/hw5/wk5.csv")

df.2015<-subset(df.full, year==2015)

plot_ly(
  data=df.2015,
  x=~income,
  y=~lifeExp,
  customdata=~population,
  color=~factor(region),
  hovertext=~country,
  hoverlabel=~population,
  size=~(log(population)),
  alpha=.8,
  type="scatter",
  mode="markers",
  hovertemplate=paste(  '<br><b>Country</b>: %{hovertext}',
                        '<br><b>Income</b>: %{x}',
  '<br><b>Life Expectancy</b>: %{y}',
  '<br><b>Population</b>: %{customdata}'
)
) %>%
  layout(
    title=list(text= "Association of Income and Life Expectancy, 2015"
             ),
    xaxis=list(title=list(text="Income" 
              )),
    yaxis=list(title=list(text="Life Expectancy" 
               )))

The above graph is interactive with one’s mouse - if you move your mouse over a dot, it will give you the following info for the specific data point: country, income, life expectancy, and population. The region (continent) continues to be color-coded.

5.2 Second Interactive Plot: Visualizing the Data by Year

wong.pal <- c("#E69F00", "#56B4E9", "#009E73","#CC79A7", "#0072B2")
wong.pal <- setNames(wong.pal, c("Asia", "Europe", "Africa", "Americas", "Oceania"))


fig2 <- df.full %>%
  plot_ly(
    x = ~income, 
    y = ~lifeExp, 
    size = ~(2*log(population)-11)^2,
    color = ~region, 
    colors = wong.pal, 
    frame = ~year,  
    text = ~paste("Country:", country,
                  "<br>Continent:", region,
                  "<br>Year:", year,
                  "<br>LifeExp:", lifeExp,
                  "<br>Pop:", population,
                  "<br>Income:", income),
    hoverinfo = "text",
    type = 'scatter',
    mode = 'markers'
  )%>%
  layout(xaxis=list(title='Income'), yaxis=list(title='Life Expectancy'), title="Association of Income and Life Expectancy, 1800-2018")

fig2 <- fig2 %>% layout(
  xaxis = list(
    type = "log"
  )
)

fig2

The above graph is able to represent all of the information from previous visualizations over every available year. Please note the scaling in the x axis, which allows a viewer to see a meaningful difference in income, even at lower levels (without it, the first century of data appears to show little horizontal change).

LS0tDQp0aXRsZTogIkNsZWFuaW5nIGFuZCBSZWZvcm1hdHRpbmcgRGF0YSBmb3IgSW50ZXJhY3RpdmUgVmlzdWFsaXphdGlvbiINCmF1dGhvcjogIkFsZXggRHJhZ29uZXR0aSINCmRhdGU6ICIzLTItMjAyNCINCm91dHB1dDoNCiAgaHRtbF9kb2N1bWVudDogDQogICAgdG9jOiB5ZXMNCiAgICB0b2NfZmxvYXQ6IHllcw0KICAgIG51bWJlcl9zZWN0aW9uczogeWVzDQogICAgdG9jX2NvbGxhcHNlZDogeWVzDQogICAgY29kZV9mb2xkaW5nOiBoaWRlDQogICAgY29kZV9kb3dubG9hZDogeWVzDQogICAgc21vb3RoX3Njcm9sbDogdHJ1ZQ0KICAgIHRoZW1lOiBsdW1lbg0KZWRpdG9yX29wdGlvbnM6DQogIGNodW5rX291dHB1dF90eXBlOiBpbmxpbmUNCi0tLQ0KYGBgez1odG1sfQ0KDQo8c3R5bGUgdHlwZT0idGV4dC9jc3MiPg0KDQovKiBDYXNjYWRpbmcgU3R5bGUgU2hlZXRzIChDU1MpIGlzIGEgc3R5bGVzaGVldCBsYW5ndWFnZSB1c2VkIHRvIGRlc2NyaWJlIHRoZSBwcmVzZW50YXRpb24gb2YgYSBkb2N1bWVudCB3cml0dGVuIGluIEhUTUwgb3IgWE1MLiBpdCBpcyBhIHNpbXBsZSBtZWNoYW5pc20gZm9yIGFkZGluZyBzdHlsZSAoZS5nLiwgZm9udHMsIGNvbG9ycywgc3BhY2luZykgdG8gV2ViIGRvY3VtZW50cy4gKi8NCg0KaDEudGl0bGUgeyAgLyogVGl0bGUgLSBmb250IHNwZWNpZmljYXRpb25zIG9mIHRoZSByZXBvcnQgdGl0bGUgKi8NCiAgZm9udC1zaXplOiAyNHB4Ow0KICBjb2xvcjogRGFya1JlZDsNCiAgdGV4dC1hbGlnbjogY2VudGVyOw0KICBmb250LWZhbWlseTogIkdpbGwgU2FucyIsIHNhbnMtc2VyaWY7DQp9DQpoNC5hdXRob3IgeyAvKiBIZWFkZXIgNCAtIGZvbnQgc3BlY2lmaWNhdGlvbnMgZm9yIGF1dGhvcnMgICovDQogIGZvbnQtc2l6ZTogMjBweDsNCiAgZm9udC1mYW1pbHk6IHN5c3RlbS11aTsNCiAgY29sb3I6IERhcmtSZWQ7DQogIHRleHQtYWxpZ246IGNlbnRlcjsNCn0NCmg0LmRhdGUgeyAvKiBIZWFkZXIgNCAtIGZvbnQgc3BlY2lmaWNhdGlvbnMgZm9yIHRoZSBkYXRlICAqLw0KICBmb250LXNpemU6IDE4cHg7DQogIGZvbnQtZmFtaWx5OiBzeXN0ZW0tdWk7DQogIGNvbG9yOiBEYXJrQmx1ZTsNCiAgdGV4dC1hbGlnbjogY2VudGVyOw0KfQ0KaDEgeyAvKiBIZWFkZXIgMSAtIGZvbnQgc3BlY2lmaWNhdGlvbnMgZm9yIGxldmVsIDEgc2VjdGlvbiB0aXRsZSAgKi8NCiAgICBmb250LXNpemU6IDIycHg7DQogICAgZm9udC1mYW1pbHk6ICJUaW1lcyBOZXcgUm9tYW4iLCBUaW1lcywgc2VyaWY7DQogICAgY29sb3I6IG5hdnk7DQogICAgdGV4dC1hbGlnbjogY2VudGVyOw0KfQ0KaDIgeyAvKiBIZWFkZXIgMiAtIGZvbnQgc3BlY2lmaWNhdGlvbnMgZm9yIGxldmVsIDIgc2VjdGlvbiB0aXRsZSAqLw0KICAgIGZvbnQtc2l6ZTogMjBweDsNCiAgICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgICBjb2xvcjogbmF2eTsNCiAgICB0ZXh0LWFsaWduOiBsZWZ0Ow0KfQ0KDQpoMyB7IC8qIEhlYWRlciAzIC0gZm9udCBzcGVjaWZpY2F0aW9ucyBvZiBsZXZlbCAzIHNlY3Rpb24gdGl0bGUgICovDQogICAgZm9udC1zaXplOiAxOHB4Ow0KICAgIGZvbnQtZmFtaWx5OiAiVGltZXMgTmV3IFJvbWFuIiwgVGltZXMsIHNlcmlmOw0KICAgIGNvbG9yOiBuYXZ5Ow0KICAgIHRleHQtYWxpZ246IGxlZnQ7DQp9DQoNCmg0IHsgLyogSGVhZGVyIDQgLSBmb250IHNwZWNpZmljYXRpb25zIG9mIGxldmVsIDQgc2VjdGlvbiB0aXRsZSAgKi8NCiAgICBmb250LXNpemU6IDE4cHg7DQogICAgZm9udC1mYW1pbHk6ICJUaW1lcyBOZXcgUm9tYW4iLCBUaW1lcywgc2VyaWY7DQogICAgY29sb3I6IGRhcmtyZWQ7DQogICAgdGV4dC1hbGlnbjogbGVmdDsNCn0NCg0KYm9keSB7IGJhY2tncm91bmQtY29sb3I6d2hpdGU7IH0NCg0KLmhpZ2hsaWdodG1lIHsgYmFja2dyb3VuZC1jb2xvcjp5ZWxsb3c7IH0NCg0KcCB7IGJhY2tncm91bmQtY29sb3I6d2hpdGU7IH0NCg0KPC9zdHlsZT4NCmBgYA0KDQpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0NCiMgRGV0ZWN0LCBpbnN0YWxsLCBhbmQgbG9hZCBwYWNrYWdlcyBpZiBuZWVkZWQuDQppZiAoIXJlcXVpcmUoImtuaXRyIikpIHsNCiAgIGluc3RhbGwucGFja2FnZXMoImtuaXRyIikNCiAgIGxpYnJhcnkoa25pdHIpDQp9DQppZiAoIXJlcXVpcmUoImxlYWZsZXQiKSkgew0KICAgaW5zdGFsbC5wYWNrYWdlcygibGVhZmxldCIpDQogICBsaWJyYXJ5KGxlYWZsZXQpDQp9DQppZiAoIXJlcXVpcmUoIkVudlN0YXRzIikpIHsNCiAgIGluc3RhbGwucGFja2FnZXMoIkVudlN0YXRzIikNCiAgIGxpYnJhcnkoRW52U3RhdHMpDQp9DQppZiAoIXJlcXVpcmUoIk1BU1MiKSkgew0KICAgaW5zdGFsbC5wYWNrYWdlcygiTUFTUyIpDQogICBsaWJyYXJ5KE1BU1MpDQp9DQppZiAoIXJlcXVpcmUoInBoeXRvb2xzIikpIHsNCiAgIGluc3RhbGwucGFja2FnZXMoInBoeXRvb2xzIikNCiAgIGxpYnJhcnkocGh5dG9vbHMpDQp9DQppZiAoIXJlcXVpcmUoImRwbHlyIikpIHsNCiAgIGluc3RhbGwucGFja2FnZXMoImRwbHlyIikNCiAgIGxpYnJhcnkoZHBseXIpDQp9DQppZiAoIXJlcXVpcmUoInRpZHlyIikpIHsNCiAgIGluc3RhbGwucGFja2FnZXMoInRpZHlyIikNCiAgIGxpYnJhcnkodGlkeXIpDQp9DQppZiAoIXJlcXVpcmUoInN0cmluZ3IiKSkgew0KICAgaW5zdGFsbC5wYWNrYWdlcygic3RyaW5nciIpDQogICBsaWJyYXJ5KHN0cmluZ3IpDQp9DQppZiAoIXJlcXVpcmUoImdncGxvdDIiKSkgew0KICAgaW5zdGFsbC5wYWNrYWdlcygiZ2dwbG90MiIpDQogICBsaWJyYXJ5KGdncGxvdDIpDQp9DQppZiAoIXJlcXVpcmUoInBsb3RseSIpKSB7DQogICBpbnN0YWxsLnBhY2thZ2VzKCJwbG90bHkiKQ0KICAgbGlicmFyeShwbG90bHkpDQp9DQojIFNwZWNpZmljYXRpb25zIG9mIG91dHB1dHMgb2YgY29kZSBpbiBjb2RlIGNodW5rcw0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFLCAgICAgICANCiAgICAgICAgICAgICAgICAgICAgICB3YXJuaW5nID0gRkFMU0UsICAgDQogICAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gVFJVRSwgICANCiAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlID0gRkFMU0UsDQogICAgICAgICAgICAgICAgICAgICAgY29tbWVudCA9IE5BKQ0KYGBgDQoNCg0KDQojIE92ZXJ2aWV3DQoNCg0KV2UgaGF2ZSBiZWVuIHRhc2tlZCB3aXRoIGNsZWFuaW5nIGFuZCByZW9yZ2FuaXppbmcgZm91ciBleGlzaXRpbmcgZGF0YSBzZXRzLiBUaGUgZm91ciBkYXRhIHNldHMgZWFjaCBjb250YWluIGRpZmZlcmVudCBkYXRhIHJlbGF0ZWQgdG8gbGlmZSBleHBlY3RhbmN5IGluIGRpZmZlcmVudCBjb3VudHJpZXMuIE91ciBnb2FsIHdpbGwgYmUgdG8gY29tYmluZSB0aGVtIGludG8gb25lIHRoYXQgY2FuIGJlIHVzZWQgZm9yIHN0YXRpc3RpY2FsIGFuYWx5c2lzIGFuZCB2aXN1YWxpemF0aW9uLg0KDQozIG9mIHRoZSA0IGRhdGEgc2V0cyBhcmUgb3JnYW5pemVkIGluIGEgJ3dpZGUnIGZvcm1hdC4gRm9yIGV4YW1wbGUsIHRoZSAnaW5jb21lJyBkYXRhIHNldCBoYXMgMjIwIGNvbHVtbnMuIENvbHVtbiAxIGlzIHRoZSBjb3VudHJ5IG9mIGludGVyZXN0LCBhbmQgZWFjaCBzdWJzZXF1ZW50IGNvbHVtbiBpcyBhIHllYXIsIGZyb20gMTgwMC0yMDE4IChpbmNsdXNpdmUpLiBFYWNoIHllYXIgdmFyaWFibGUgc3RhcnRzIHdpdGggYSBjYXBpdGFsICdYJy4NCmBgYHtyLCBlY2hvPUZBTFNFfQ0KaXBwPC1yZWFkLmNzdigiaHR0cHM6Ly9wZW5nZHNjaS5naXRodWIuaW8vZGF0YXNldHMvaW5jb21lX3Blcl9wZXJzb24uY3N2IikNCmxleTwtcmVhZC5jc3YoImh0dHBzOi8vcGVuZ2RzY2kuZ2l0aHViLmlvL2RhdGFzZXRzL2xpZmVfZXhwZWN0YW5jeV95ZWFycy5jc3YiKQ0KcG9wPC1yZWFkLmNzdigiaHR0cHM6Ly9wZW5nZHNjaS5naXRodWIuaW8vZGF0YXNldHMvcG9wdWxhdGlvbl90b3RhbC5jc3YiKQ0KY3I8LXJlYWQuY3N2KCJodHRwczovL3Blbmdkc2NpLmdpdGh1Yi5pby9kYXRhc2V0cy9jb3VudHJpZXNfdG90YWwuY3N2IikNCmBgYA0KDQoNCg0KIyBDbGVhbmluZyBhbmQgUmUtZm9ybWF0dGluZyB0aGUgRGF0YQ0KDQoNCldlIHdpbGwgZmlyc3QgY29uZGVuc2UgdGhvc2UgMyBkYXRhIHNldHMgdG8gYSBkYXRhIHNldCB3aXRoIDMgY29sdW1ucy4gVGhpcyB3aWxsIGFsbG93IGFuIGVhc2llciBtZXJnZS4gSW4gdGhlIHByb2Nlc3Mgb2YgZG9pbmcgdGhpcywgd2Ugd2lsbCByZW1vdmUgdGhlICJYIiBmcm9tIHRoZSBzdGFydCBvZiBlYWNoIHllYXIuDQpgYGB7cn0NCmlwcC5sb25nIDwtIGlwcCAlPiUNCiAgcGl2b3RfbG9uZ2VyKGNvbHMgPSBzdGFydHNfd2l0aCgiWCIpLCBuYW1lc190byA9ICJ5ZWFyIiwgdmFsdWVzX3RvID0gImluY29tZSIpICU+JQ0KICBtdXRhdGUoeWVhciA9IGFzLm51bWVyaWMoc3RyX3JlbW92ZSh5ZWFyLCAiXlgiKSkpIA0KDQpsZXkubG9uZyA8LSBsZXkgJT4lDQogIHBpdm90X2xvbmdlcihjb2xzID0gc3RhcnRzX3dpdGgoIlgiKSwgbmFtZXNfdG8gPSAieWVhciIsIHZhbHVlc190byA9ICJsaWZlRXhwIikgJT4lDQogIG11dGF0ZSh5ZWFyID0gYXMubnVtZXJpYyhzdHJfcmVtb3ZlKHllYXIsICJeWCIpKSkgDQoNCnBvcC5sb25nIDwtIHBvcCAlPiUNCiAgcGl2b3RfbG9uZ2VyKGNvbHMgPSBzdGFydHNfd2l0aCgiWCIpLCBuYW1lc190byA9ICJ5ZWFyIiwgdmFsdWVzX3RvID0gInBvcHVsYXRpb24iKSAlPiUNCiAgbXV0YXRlKHllYXIgPSBhcy5udW1lcmljKHN0cl9yZW1vdmUoeWVhciwgIl5YIikpKSANCmBgYA0KDQpXZSBoYXZlIGJlZW4gYXNrZWQgdG8gY3JlYXRlIGEgZGF0YXNldCBjYWxsZWQgYExpZmVFeHBJbmNvbWAgdGhhdCBvbmx5IGNvbnRhaW5zIExpZmUgRXhwZWN0YW5jeSBhbmQgSW5jb21lLiBUaGUgcmVxdWVzdGVkIGZvcm1hdCBpcyBsb3dlciBjYXNlIGZvciBhbGwgdmFyaWFibGVzIGV4Y2VwdCBmb3IgJ2xpZmVFeHAnIGZvciBsaWZlIGV4cGVjdGFuY3kuDQoNCldlIHdpbGwgYWxzbyBtZXJnZSB0aGUgcmVtYWluaW5nIGRhdGEgaW50byBvbmUgc2V0LiBUaGUgZmluYWwgZGF0YSBzZXRzIHdpbGwgcmVwbGFjZSAnZ2VvJyB3aXRoICdjb3VudHJ5JywgcGVyIHJlcXVlc3Qgb2Ygb3VyIGFzc2lnbm1lbnQuDQpgYGB7cn0NCkxpZmVFeHBJbmNvbSA8LSBtZXJnZShpcHAubG9uZywgbGV5LmxvbmcsIGJ5ID0gYygiZ2VvIiwgInllYXIiKSkNCg0KbWVyZ2UuZGYuMSA8LSBtZXJnZShMaWZlRXhwSW5jb20sIHBvcC5sb25nLCBieSA9IGMoImdlbyIsICJ5ZWFyIikpDQoNCmNvbG5hbWVzKGNyKVsxXTwtImdlbyINCm1lcmdlLmRmLjIgPC1tZXJnZShtZXJnZS5kZi4xLCBjciwgYnkgPSAiZ2VvIikNCg0KY29sbmFtZXMoTGlmZUV4cEluY29tKVsxXTwtImNvdW50cnkiDQpjb2xuYW1lcyhtZXJnZS5kZi4yKVsxXTwtImNvdW50cnkiDQoNCiN3cml0ZS5jc3YobWVyZ2UuZGYuMiwgIkM6XFxVc2Vyc1xcQWxleFxcRG9jdW1lbnRzXFxSXFxHcmFkXFw1NTNcXGRhdGFzZXRzXFx3azUuY3N2IikNCmBgYA0KDQpPdXIgZGF0YSBpcyBub3cgaW4gb25lIGRhdGFzZXQsIHJlYWR5IGZvciB2aXN1YWxpemF0aW9uLiBBIGNvcHkgb2YgdGhpcyBkYXRhIGNhbiBiZSBmb3VuZCBhdCBodHRwczovL3Jhdy5naXRodWJ1c2VyY29udGVudC5jb20vQWxleERyYWdvbmV0dGkvU1RBNTUzL21haW4vaHc1L3drNS5jc3YNCg0KDQoNCiMgU3Vic2V0dGluZyB0aGUgRGF0YSB0byBBbmFseXplIHRoZSBZZWFyIDIwMDANCg0KDQpXZSBoYXZlIGJlZW4gYXNrZWQgdG8gY3JlYXRlIGEgZGF0YXNldCBmb3IgdGhlIHllYXIgMjAwMCBhbmQgdmlzdWFsaXplIGl0LiBGaXJzdCwgd2UgbXVzdCBjcmVhdGUgdGhlIGRhdGE6DQpgYGB7cn0NCiIyMDAwZGF0YSI8LXN1YnNldChtZXJnZS5kZi4yLCB5ZWFyPT0yMDAwKQ0KI2ZvciBzb21lIHJlYXNvbiwgUiBlbmNvdW50ZXJzIGFuIGVycm9yIHdoaWxlIHZpZXdpbmcgIjIwMDBkYXRhIiwgc28gSSBoYXZlIGNyZWF0ZWQgYSBzZWNvbmQgZGYgdGhhdCBpcyBpZGVudGljYWwNCnR3b3Rob3VzYW5kZGF0YTwtc3Vic2V0KG1lcmdlLmRmLjIsIHllYXI9PTIwMDApDQoNCiN3cml0ZS5jc3YodHdvdGhvdXNhbmRkYXRhLCAiQzpcXFVzZXJzXFxBbGV4XFxEb2N1bWVudHNcXFJcXEdyYWRcXDU1M1xcZGF0YXNldHNcXDIwMDBkYXRhLmNzdiIpDQpgYGANCg0KQSBjb3B5IG9mIHRoZSBhYm92ZSBkYXRhIGNhbiBiZSBmb3VuZCBhdCBodHRwczovL3Jhdy5naXRodWJ1c2VyY29udGVudC5jb20vQWxleERyYWdvbmV0dGkvU1RBNTUzL21haW4vaHc1LzIwMDBkYXRhLmNzdiANCg0KDQojIFZpc3VhbGl6aW5nIHRoZSBEYXRhIGZvciB0aGUgWWVhciAyMDAwDQoNCldlIGhhdmUgYmVlbiBhc2tlZCB0byB2aXN1YWxseSByZXByZXNlbnQgZGF0YSBmcm9tIGFsbCBmb3VyIHNldHMgaW4gb25lIGdyYXBoLCBhbmQgc3BlY2lmaWNhbGx5IGFza2VkIHRvIHJlcHJlc2VudCByZWdpb24gd2l0aCBhIGNvbG9yLWNvZGUuIFBvcHVsYXRpb24gc2l6ZSBiZWluZyByZXByZXNlbnRlZCB3aXRoIHBvaW50IHNpemUgc2VlbXMgbG9naWNhbCwgbWVhbmluZyBvdXIgZ3JhcGggd2lsbCBoYXZlIGluY29tZSBvbiB0aGUgWCBheGlzIGFuZCBMaWZlIEV4cGVjdGFuY3kgb24gdGhlIFkgYXhpcy4gVGhpcyB1c2VzIHRoZSBgZ2dwbG90YCBwYWNrYWdlLg0KYGBge3J9DQpsaWZlLmV4cC5wbG90PC1nZ3Bsb3QodHdvdGhvdXNhbmRkYXRhLCBhZXMgKHg9aW5jb21lLCB5PWxpZmVFeHAsIGNvbG9yPXJlZ2lvbiwgc2l6ZT1wb3B1bGF0aW9uKSkrZ2VvbV9wb2ludCgpK3NjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXM9YygiIzMzMjI4OCIsICIjMTE3NzMzIiwgIiM4OENDRUUiLCAiI0NDNjY3NyIsICIjODgyMjU1IikpKw0KICBsYWJzKA0KICB4PSJJbmNvbWUiLA0KICB5PSJMaWZlIEV4cGVjdGFuY3kiLA0KICBzaXplPSJQb3B1bGF0aW9uIiwNCiAgY29sb3I9IlJlZ2lvbiIsDQogIHRpdGxlPSJBc3NvY2lhdGlvbiBCZXR3ZWVuIEluY29tZSBhbmQgTGlmZSBFeHBlY3RhbmN5IikNCg0KbGlmZS5leHAucGxvdA0KYGBgDQoNCk91ciBncmFwaCBzaG93cyBldmlkZW5jZSBvZiBhIGZldyB0cmVuZHM6IGZpcnN0LCBBZnJpY2FuIGFuZCBBc2lhbiBjb3VudHJpZXMgYXBwZWFyIHRvIGhhdmUgaW5jcmVkaWJseSBoaWdoIHZhcmlhbmNlIGZvciBsaWZlIGV4cGVjdGFuY3kuIEFkZGl0aW9uYWxseSwgdGhlcmUgYXBwZWFycyB0byBiZSBhIGxpbmVhciByZWxhdGlvbnNoaXAgYmV0d2VlbiBpbmNvbWUgYW5kIGxpZmUgZXhwZWN0YW5jeSwgYnV0IHRoYXQgKG9idmlvdXNseSkgbXVzdCBzdG9wIHNvbWV3aGVyZS4gSXQgYXBwZWFycyB0aGF0IGJleW9uZCBhbiBhdmVyYWdlIGluY29tZSBvZiB+JDQwLDAwMCAofiQ3MywwMDAgYWRqdXN0ZWQgZm9yIDIwMjQsIHVzaW5nIHRoZSBVUyBCdXJlYXUgb2YgTGFib3IgU3RhdGlzdGljcycgQ1BJIEluZmxhdGlvbiBDYWxjdWxhdG9yKSwgdGhlIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIGluY29tZSBhbmQgbGlmZSBleHBlY3RhbmN5IHBsYXRlYXVzLg0KDQpBcyB0aGlzIGlzIG9ubHkgYW4gYW5hbHlzaXMgb2Ygb25lIHllYXIsIHdlIHdvdWxkIHN1Z2dlc3QgYW5hbHl6aW5nIHRoZSByZWxhdGlvbnNoaXAgYmV0d2VlbiBpbmNvbWUsIHBvcHVsYXRpb24gc2l6ZSwgYW5kIGxpZmUgZXhwZWN0YW5jeSBhY3Jvc3MgbXVsdGlwbGUgeWVhcnMgb2YgaW50ZXJlc3QgdG8gc2VlIGlmIG9yIGhvdyB0aGlzIHJlbGF0aW9uc2hpcCBjaGFuZ2VzLCBvciB3aGF0IGl0IGF2ZXJhZ2VzIHRvIG92ZXIgYW4gZXJhIG9mIGludGVyZXN0Lg0KDQoNCg0KIyBVc2luZyBJbnRlcmFjdGl2ZSBQbG90cyB0byBJbXByb3ZlIFZpc3VhbGl6YXRpb24NCg0KDQpXaGlsZSBvdXIgcHJldmlvdXMgcGxvdCBwcm92aWRlcyBhbiBvdmVydmlldyBhbmQgY2FuIGhlbHAgYXNzZXNzIHRyZW5kcywgd2Ugd2lsbCB1c2UgdHdvIGludGVyYWN0aXZlIHZpc3VhbHMgdG8gYWxsb3cgZm9yIGRlZXBlciBlbmdhZ2VtZW50IHdpdGggZGF0YS4gT3VyIGZpcnN0IGdyYXBoIHdpbGwgbG9vayBzaW1pbGFyIHRvIG91ciBsYXN0LCBidXQgYWxsb3cgYSByZWFkZXIgdG8gY2hlY2sgYSBjb3VudHJ5IChhbmQgaXRzIGRhdGEpLiBPdXIgc2Vjb25kIHdpbGwgc2hvdyBob3cgdGhlIGRhdGEgaGFzIGNoYW5nZWQgeWVhciB0byB5ZWFyLiBGb3Igb3VyIGludGVyYWN0aXZlIHBsb3RzLCB3ZSB3aWxsIHVzZSB0aGUgYHBsb3RseWAgcGFja2FnZS4NCg0KDQojIyBGaXJzdCBJbnRlcmFjdGl2ZSBwbG90OiBJbmNvbWUgYW5kIExpZmUgRXhwZWN0YW5jeSBpbiAyMDE1DQoNCg0KYGBge3J9DQpkZi5mdWxsPC1yZWFkLmNzdigiaHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL0FsZXhEcmFnb25ldHRpL1NUQTU1My9tYWluL2h3NS93azUuY3N2IikNCg0KZGYuMjAxNTwtc3Vic2V0KGRmLmZ1bGwsIHllYXI9PTIwMTUpDQoNCnBsb3RfbHkoDQogIGRhdGE9ZGYuMjAxNSwNCiAgeD1+aW5jb21lLA0KICB5PX5saWZlRXhwLA0KICBjdXN0b21kYXRhPX5wb3B1bGF0aW9uLA0KICBjb2xvcj1+ZmFjdG9yKHJlZ2lvbiksDQogIGhvdmVydGV4dD1+Y291bnRyeSwNCiAgaG92ZXJsYWJlbD1+cG9wdWxhdGlvbiwNCiAgc2l6ZT1+KGxvZyhwb3B1bGF0aW9uKSksDQogIGFscGhhPS44LA0KICB0eXBlPSJzY2F0dGVyIiwNCiAgbW9kZT0ibWFya2VycyIsDQogIGhvdmVydGVtcGxhdGU9cGFzdGUoICAnPGJyPjxiPkNvdW50cnk8L2I+OiAle2hvdmVydGV4dH0nLA0KICAgICAgICAgICAgICAgICAgICAgICAgJzxicj48Yj5JbmNvbWU8L2I+OiAle3h9JywNCiAgJzxicj48Yj5MaWZlIEV4cGVjdGFuY3k8L2I+OiAle3l9JywNCiAgJzxicj48Yj5Qb3B1bGF0aW9uPC9iPjogJXtjdXN0b21kYXRhfScNCikNCikgJT4lDQogIGxheW91dCgNCiAgICB0aXRsZT1saXN0KHRleHQ9ICJBc3NvY2lhdGlvbiBvZiBJbmNvbWUgYW5kIExpZmUgRXhwZWN0YW5jeSwgMjAxNSINCiAgICAgICAgICAgICApLA0KICAgIHhheGlzPWxpc3QodGl0bGU9bGlzdCh0ZXh0PSJJbmNvbWUiIA0KICAgICAgICAgICAgICApKSwNCiAgICB5YXhpcz1saXN0KHRpdGxlPWxpc3QodGV4dD0iTGlmZSBFeHBlY3RhbmN5IiANCiAgICAgICAgICAgICAgICkpKQ0KYGBgDQoNClRoZSBhYm92ZSBncmFwaCBpcyBpbnRlcmFjdGl2ZSB3aXRoICBvbmUncyBtb3VzZSAtIGlmIHlvdSBtb3ZlIHlvdXIgbW91c2Ugb3ZlciBhIGRvdCwgaXQgd2lsbCBnaXZlIHlvdSB0aGUgZm9sbG93aW5nIGluZm8gZm9yIHRoZSBzcGVjaWZpYyBkYXRhIHBvaW50OiBjb3VudHJ5LCBpbmNvbWUsIGxpZmUgZXhwZWN0YW5jeSwgYW5kIHBvcHVsYXRpb24uIFRoZSByZWdpb24gKGNvbnRpbmVudCkgY29udGludWVzIHRvIGJlIGNvbG9yLWNvZGVkLg0KDQoNCg0KIyMgU2Vjb25kIEludGVyYWN0aXZlIFBsb3Q6IFZpc3VhbGl6aW5nIHRoZSBEYXRhIGJ5IFllYXINCg0KDQpgYGB7cn0NCndvbmcucGFsIDwtIGMoIiNFNjlGMDAiLCAiIzU2QjRFOSIsICIjMDA5RTczIiwiI0NDNzlBNyIsICIjMDA3MkIyIikNCndvbmcucGFsIDwtIHNldE5hbWVzKHdvbmcucGFsLCBjKCJBc2lhIiwgIkV1cm9wZSIsICJBZnJpY2EiLCAiQW1lcmljYXMiLCAiT2NlYW5pYSIpKQ0KDQoNCmZpZzIgPC0gZGYuZnVsbCAlPiUNCiAgcGxvdF9seSgNCiAgICB4ID0gfmluY29tZSwgDQogICAgeSA9IH5saWZlRXhwLCANCiAgICBzaXplID0gfigyKmxvZyhwb3B1bGF0aW9uKS0xMSleMiwNCiAgICBjb2xvciA9IH5yZWdpb24sIA0KICAgIGNvbG9ycyA9IHdvbmcucGFsLCANCiAgICBmcmFtZSA9IH55ZWFyLCAgDQogICAgdGV4dCA9IH5wYXN0ZSgiQ291bnRyeToiLCBjb3VudHJ5LA0KICAgICAgICAgICAgICAgICAgIjxicj5Db250aW5lbnQ6IiwgcmVnaW9uLA0KICAgICAgICAgICAgICAgICAgIjxicj5ZZWFyOiIsIHllYXIsDQogICAgICAgICAgICAgICAgICAiPGJyPkxpZmVFeHA6IiwgbGlmZUV4cCwNCiAgICAgICAgICAgICAgICAgICI8YnI+UG9wOiIsIHBvcHVsYXRpb24sDQogICAgICAgICAgICAgICAgICAiPGJyPkluY29tZToiLCBpbmNvbWUpLA0KICAgIGhvdmVyaW5mbyA9ICJ0ZXh0IiwNCiAgICB0eXBlID0gJ3NjYXR0ZXInLA0KICAgIG1vZGUgPSAnbWFya2VycycNCiAgKSU+JQ0KICBsYXlvdXQoeGF4aXM9bGlzdCh0aXRsZT0nSW5jb21lJyksIHlheGlzPWxpc3QodGl0bGU9J0xpZmUgRXhwZWN0YW5jeScpLCB0aXRsZT0iQXNzb2NpYXRpb24gb2YgSW5jb21lIGFuZCBMaWZlIEV4cGVjdGFuY3ksIDE4MDAtMjAxOCIpDQoNCmZpZzIgPC0gZmlnMiAlPiUgbGF5b3V0KA0KICB4YXhpcyA9IGxpc3QoDQogICAgdHlwZSA9ICJsb2ciDQogICkNCikNCg0KZmlnMg0KYGBgDQoNClRoZSBhYm92ZSBncmFwaCBpcyBhYmxlIHRvIHJlcHJlc2VudCBhbGwgb2YgdGhlIGluZm9ybWF0aW9uIGZyb20gcHJldmlvdXMgdmlzdWFsaXphdGlvbnMgb3ZlciBldmVyeSBhdmFpbGFibGUgeWVhci4gUGxlYXNlIG5vdGUgdGhlIHNjYWxpbmcgaW4gdGhlIHggYXhpcywgd2hpY2ggYWxsb3dzIGEgdmlld2VyIHRvIHNlZSBhIG1lYW5pbmdmdWwgZGlmZmVyZW5jZSBpbiBpbmNvbWUsIGV2ZW4gYXQgbG93ZXIgbGV2ZWxzICh3aXRob3V0IGl0LCB0aGUgZmlyc3QgY2VudHVyeSBvZiBkYXRhIGFwcGVhcnMgdG8gc2hvdyBsaXR0bGUgaG9yaXpvbnRhbCBjaGFuZ2UpLg==